﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace LxCFD
{
    public class BiCGBase
    {
        public static double rho;
        public static double alpha;
        public static double omega;
        public static double beta;
        protected static bool GetIsNeededToBreak(double d)
        {
            return d < 1e-20;
        }
        public static bool Initialize_Step2()
        {
            rho = 1;
            alpha = 1;
            omega = 1;
            return Cal_rhobeta();
        }
        public static bool Cal_rhobeta()//1.2
        {
            ThreadsMath.GetSum(out double rho_new, out double sum2, out double sum3);
            if (GetIsNeededToBreak(rho_new)) return true;
            if (GetIsNeededToBreak(omega)) return true;
            beta = (rho_new / rho) * (alpha / omega);
            rho = rho_new;
            return false;
        }
        public static bool Cal_alpha()//5.2
        {
            ThreadsMath.GetSum(out double r0v, out double sum2, out double sum3);
            if (GetIsNeededToBreak(r0v)) return true;
            alpha = rho / r0v;
            return false;
        }
        public static bool Cal_omega()//9.2
        {
            ThreadsMath.GetSum(out double ts, out double tt, out double sum3);
            if (GetIsNeededToBreak(tt)) return true;
            omega = ts / tt;
            return false;
        }
    }
}
//public static volatile bool _IsNeededToBreak;
//protected static bool SetIsNeededToBreak(double d)
//{
//    _IsNeededToBreak = d < 1e-20;
//    return GetIsNeededToBreak();
//}
//public static bool GetIsNeededToBreak()
//{
//    return _IsNeededToBreak;
//}
//public static void DotProduct(IndexNumber indexNumber, double[] array1, double[] array2, int taskIndex)
//{
//    indexNumber.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
//    double temp = 0;
//    for (; i1 < endp1; i1++)
//    {
//        temp += array1[i1] * array2[i1];
//    }
//    TasksControl.Storage1[taskIndex] += temp;
//}

//public static void Cal_pArray(IndexNumber indexNumber, double[] p, double[] r, double[] v, int taskIndex)//2
//{
//    indexNumber.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        p[i1] = r[i1] + beta * (p[i1] - omega * v[i1]);
//    }
//}
//public static void DInversePrecond(IndexNumber indexNumber, double[] left, double[] ADiag, double[] right, int taskIndex)
//{
//    indexNumber.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        left[i1] = right[i1] / ADiag[i1];
//    }
//}

//public static void Cal_rMinus(IndexNumber indexNumber, double[] r, double factor, double[] subtrahend, int taskIndex)
//{
//    indexNumber.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        r[i1] -= factor * subtrahend[i1];
//    }
//}

//public static void cal_xArray(IndexNumber indexNumber, double[] x, double[] y, double[] z, int taskIndex)
//{
//    indexNumber.CellIDs.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        x[i1] += alpha * y[i1] + omega * z[i1];
//    }
//}
//protected static double calArraySumAndReset(decimal[] array)
//{
//    decimal result = 0;
//    for (int i1 = 0; i1 < array.Length; i1++)
//    {
//        result += array[i1];
//        array[i1] = 0;
//    }
//    return (double)result;
//}
//public interface IBiCGStabPreconditioning
//{
//    void CalKInverseProduct(IndexNumber indexNumber, double[] resultArray, double[] rightHandArray, int taskIndex);
//    void CalKInversets(out double fenzi, out double fenmu, IndexNumber indexNumber, double[] tArray, double[] sArray, int taskIndex);
//}
//public void cal_omega(IndexNumber indexNumber, int taskIndex)
//{
//    indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//    double temp1 = 0, temp2 = 0;
//    for (; i1 < endp1; i1++)
//    {
//        double stemp = r[i1];
//        temp1 += t[i1] * stemp;
//        temp2 += stemp * stemp;
//    }
//    TasksControl.Storage1[taskIndex] += temp1;
//    TasksControl.Storage2[taskIndex] += temp2;
//}
//public static void CalDotProduct(int start, int endp1, double[] array1, double[] array2, int taskIndex)
//{
//    double rhoAtitemp = 0;
//    for (; start < endp1; start++)
//    {
//        rhoAtitemp += array1[start] * array2[start];
//    }
//    TasksControl.Storage1[taskIndex] += rhoAtitemp;
//}
//public static void CalArrayMinus(int start, int endp1, double[] minuend, double factor, double[] subtrahend)
//{
//    for (; start < endp1; start++)
//    {
//        minuend[start] -= factor * subtrahend[start];
//    }
//}
//public static void Calpi(int start, int endp1, double[] p, double[] r, double beta, double omega, double[] v)
//{
//    for (; start < endp1; start++)
//    {
//        p[start] = r[start] + beta * (p[start] - omega * v[start]);
//    }
//}
//public static void Calx(int start, int endp1, double[] xArray, double alpha, double[] p, double omega, double[] s)
//{
//    for (; start < endp1; start++)
//    {
//        xArray[start] += alpha * p[start] + omega * s[start];
//    }
//}
//public void Cal_sArray(IndexNumber indexNumber, int taskIndex)
//{
//    cal_rMinus(indexNumber, alpha, v, taskIndex);
//}
//protected void cal_y(IndexNumber indexNumber, int taskIndex)//3
//{
//    Precond.CalKInverseProduct(indexNumber, y, pAti, taskIndex);
//}
//protected void cal_vAti(IndexNumber indexNumber, int taskIndex)//4
//{
//    AProduct.CalAProduct(indexNumber, vAti, y, taskIndex);
//}
//protected void cal_rAt0ProductvAti(IndexNumber indexNumber, int taskIndex)//5.1
//{
//    indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//    double temp = 0;
//    for (; i1 < endp1; i1++)
//    {
//        temp += rAt0[i1] * vAti[i1];
//    }
//    TasksControl.Storage1[taskIndex] += temp;
//}
//protected void cal_s(IndexNumber indexNumber, int taskIndex)//6
//{
//    indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        s[i1] = r[i1] - alpha * vAti[i1];
//    }
//}
//protected void cal_z(IndexNumber indexNumber, int taskIndex)//7
//{
//    Precond.CalKInverseProduct(indexNumber, z, s, taskIndex);
//}
//protected void cal_t(IndexNumber indexNumber, int taskIndex)//8
//{
//    AProduct.CalAProduct(indexNumber, t, z, taskIndex);
//}
//protected void cal_KtKsKtKt(IndexNumber indexNumber, int taskIndex)//9.1
//{
//    Precond.CalKInversets(out double fenzi, out double fenmu, indexNumber, t, s, taskIndex);
//    TasksControl.Storage1[taskIndex] += fenzi;
//    TasksControl.Storage2[taskIndex] += fenmu;
//}
//protected void cal_xAti(IndexNumber indexNumber, int taskIndex)//10
//{
//    indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        x[i1] += alpha * y[i1] + omega * z[i1];
//    }
//}
//protected void cal_rAti_1(IndexNumber indexNumber, int taskIndex)//11,但是改为了rAti-1
//{
//    indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//    for (; i1 < endp1; i1++)
//    {
//        r[i1] = s[i1] - wAti_1 * t[i1];
//    }
//}
//public void Cal_rho(IndexNumber indexNumber, int taskIndex)//1.1
//{
//    cal_DotProduct(indexNumber, r0, r, taskIndex);
//}
//public void Cal_alphaPart1(IndexNumber indexNumber, int taskIndex)
//{
//    cal_DotProduct(indexNumber, r0, v, taskIndex);
//}
//indexNumber.CellIdx.GetSeg(out int i1, out int endp1, taskIndex);
//double rhoAtitemp = 0;
//for (; i1 < endp1; i1++)
//{
//    rhoAtitemp += rAt0[i1] * r[i1];
//}
//TasksControl.Storage1[taskIndex] += rhoAtitemp;